package com.home.moon.chat.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.digest.MD5;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.home.moon.chat.mapper.FollowsMapper;
import com.home.moon.chat.mapper.UserMapper;
import com.home.moon.chat.dto.UserAddDto;
import com.home.moon.chat.model.Follows;
import com.home.moon.chat.model.Users;
import com.home.moon.chat.service.BaseService;
import com.home.moon.util.JWTUtil;
import com.home.moon.util.RedisUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author auto
 */
@Service
public class UserServiceImpl implements BaseService {
    private ReentrantLock lock = new ReentrantLock();
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private  FollowsMapper followsMapper;
    @Autowired
    private RedisUtil redisUtil;

    public int addUser(UserAddDto dto){
        lock.lock();
        try {
            Users user = new Users();
            BeanUtils.copyProperties(dto,user);
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            user.setPassword(MD5.create().digestHex(user.getPassword()+user.getUsername()+"红娘"));
           return userMapper.insert(user);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return 0;
    }

    public String login(Users query, HttpServletResponse response){
        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Users::getUsername,query.getUsername());
        Users user = userMapper.selectOne(wrapper);
        if(Optional.ofNullable(user).isEmpty()){
            throw new RuntimeException("未查到该用户!");
        }
        MD5.create().digestHex(query.getPassword() + query.getUsername() + "红娘").equals(user.getPassword());
//        Map map = new HashMap(1);
//        map.put("username",user.getUsername());
        String jwt = JWTUtil.getToken(user.getUsername(),DateUtil.offset(new Date(), DateField.HOUR,24),
                Algorithm.HMAC256(user.getPassword()));
        Cookie cookie = new Cookie("token",jwt);
        response.addCookie(cookie);
        redisUtil.put(jwt,query.getUsername(),1, TimeUnit.DAYS);
        return jwt;
    }

    public Users getUser(Users user){
        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Users::getId,user.getId());
        return userMapper.selectOne(wrapper);
    }

    public int addFollow(Follows follow){
        return followsMapper.insert(follow);
    }

    public List<Users> getFollows(Users user){
        LambdaQueryWrapper<Follows> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Follows::getUserId,user.getId());
        List<Follows> list = followsMapper.selectList(wrapper);
        List<Users> usersList = new ArrayList<>();
        for(Follows f:list){
            LambdaQueryWrapper<Users> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Users::getId,f.getFollowUserId());
            Users u = userMapper.selectOne(wrapper1);
            usersList.add(u);
        }
        return usersList;
    }

    public List<Users> getMyFollows(Users user){
        LambdaQueryWrapper<Follows> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Follows::getFollowUserId,user.getId());
        List<Follows> list = followsMapper.selectList(wrapper);
        List<Users> usersList = new ArrayList<>();
        for(Follows f:list){
            LambdaQueryWrapper<Users> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Users::getId,f.getFollowUserId());
            Users u = userMapper.selectOne(wrapper1);
            usersList.add(u);
        }
        return usersList;
    }

    public List<Users> getBingo(Users user){
        LambdaQueryWrapper<Follows> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Follows::getBingo,1);
        wrapper.eq(Follows::getUserId,user.getId()).or().eq(Follows::getFollowUserId,user.getId());
        List<Follows> list = followsMapper.selectList(wrapper);
        List<Users> usersList = new ArrayList<>();
        for(Follows f:list){
            LambdaQueryWrapper<Users> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Users::getId,f.getFollowUserId());
            Users u = userMapper.selectOne(wrapper1);
            usersList.add(u);
        }
        return usersList;
    }

}
